var event = require('../../core/event');
var util = require('../../util/index');
var Log = require('../../util/logger');
var ui = require('./ui');
var io = require('../io/ui');
var note = require('../note/manager');
var path = require('path');
var notify = require('../notify/ui');
var config = require('../../core/config');
var sound = require('../audio/sound');
var fs = require('fs');
var $ = window.$;

var _init = false;
var _timing = null;
var _edit = null;

var ret = {
	init: function(){
		if(_init){
			return;
		}

		this.current = null;

		ui.setManager(this);
		ui.init();

		event.bindOwner("sample", 'sample',this);
		event.bindOwner('note', 'sample',this);
		event.bind(event.events.global.drop, 'sample', this);

		Log.log('sample init');
		_init = true;
	},

	/**
	 * 内部, 静默的检查Chart各种参数的合法性
	 * Chart从外部输入, 默认只检查几个关键路径参数
	 * 假定this.chart 已存在
	 */
	validate: function(isMCE){
		var samples = util.getJsonChainValue(this.chart, 'extra.samples');
		if(!samples || samples.length == 0){
			if(!isMCE){
				var list = {};
				//重建samples
				var notes = this.chart.note;
				for(var i=0;i<notes.length;i++){
					if(notes[i].sound){
						list[notes[i].sound] = true;
					}
				}
				var _list = [];
				for(var key in list){
					if(list.hasOwnProperty(key)){
						_list.push({
							name: key
						});
					}
				}
				util.setJsonChainValue(this.chart, 'extra.samples', _list);
			}else{
				util.setJsonChainValue(this.chart, 'extra.samples', []);
			}
		}
		this.editInfo = util.getJsonChainValue(this.chart, 'extra.samples');
	},

	onEvent: function (e, param) {
		var self = this;
		if(e == event.events.note.load){
			//从note中读取音频部分
			var chart = note.getNote(param.key);
			if(!chart){
				return;
			}
			this.chart = chart;
			this.current = null;
			this.validate(param.mce);

			//刷新列表
			ui.sync();
		}else if(e == event.events.note.unload){
			this.chart = null;
			this.current = null;
			ui.clear();
			sound.unloadAll();
		}else if(e == event.events.sample.load){
			io.getSoundPath().then(function(file){
				if(file){
					if(typeof file == 'object'){
						for(var i=0;i<file.length;i++){
							self.addSample(file[i]);
						}
					}else{
						self.addSample(file);
					}
				}
			});
		}else if(e == event.events.sample.add){
			this.addSample(param.file);
		}else if(e == event.events.sample.edit){
			if(!param || !param.length){
				return;
			}
			if(_edit == null){
				_edit = require('./edit.js');
			}
			_edit.setManager(this);
			_edit.init();
			_edit.show(param);

			return event.result.stopAll;
		}else if(e == event.events.sample.timing){
			if(_timing == null){
				_timing = require('./timing.js');
			}
			_timing.setManager(this);
			_timing.init();
			_timing.show(param);

			return event.result.stopAll;
		}else if(e == event.events.global.drop){
			if(!param){
				return;
			}
			var target = $(param.target);
			if(!(target.attr('id') == 'tool_sample') || target.parents("#tool_sample").size() > 0){
				return;
			}
			this.onFileDrop(param.dataTransfer.files);
			return event.result.stopAll;
		}
	},

	getCurrent: function(){
		return this.current;
	},

	/**
	 * 数据操纵
	 */

	addSample: function(file, dir){
		if(!this.chart){
			return;
		}
		var name = path.basename(file);
		//检查重复
		if(this.isExist(name)){
			notify.addNotify({
				msg: config.i18n("tip01")
			});
			return;
		}
		var obj = {
			name: name
		};
		note.importFile(file, true);
		if(dir){
			var _dir = this.getDir(dir);
			if(!_dir){
				_dir = {
					name: dir,
					list:[],
					type:'dir'
				};
				this.editInfo.push(_dir);
			}
			_dir.list = _dir.list || [];  //确保
			_dir.list.push(obj);
			//没有sync, 要整体同步
		}else{
			this.editInfo.push(obj);
			ui.syncSingle(obj);
		}
		event.trigger(event.events.note.change);
	},

	removeSample: function (name, list) {
		if(!list){
			list = this.editInfo;
		}
		if(!list || !list.length){
			return false;
		}
		var flag = false;
		for(var i=0;i<list.length;i++){
			if(list[i].name == name){  //dir 也能删
				list.splice(i, 1);
				//fs.unlinkSync(note.getFilePath(name)); //删除文件
				flag = true;
				break;
			}else if(list[i].type == 'dir'){
				if(this.removeSample(name, list[i].list || [])){
					flag = true;
					break;
				}
			}
		}
		//在递归中, 可能会触发2次, 不过没关系
		if(flag){
			event.trigger(event.events.note.change);
		}
		return flag;
	},

	/**
	 * 内部辅助
	 */

	isExist: function (name, list) {
		return this.getSample(name, list) != null;
	},

	/**
	 * 废弃
	 * @param name
	 * @param list
	 * @returns {*}
	 */
	getSample: function(name, list){
		if(!list){
			list = this.editInfo;
		}
		if(!list || !list.length){
			return null;
		}
		for(var i=0;i<list.length;i++){
			if(list[i].type == 'dir'){
				var found = this.getSample(name, list[i].list || []);
				if(found){
					return found;
				}
			}else if(list[i].name == name){
				return list[i];
			}
		}
		return null;
	},

	getDir: function(name){
		var	list = this.editInfo;
		if(!list || !list.length){
			return null;
		}
		for(var i=0;i<list.length;i++){
			if(list[i].type == 'dir' && list[i].name == name){
				return list[i];
			}
		}
		return null;
	},

	/**
	 * drop事件
	 * @param arr 对应的路径数组, 里面可能有目录, 但是目录只处理一层
	 */
	onFileDrop: function(arr){
		var self = this;
		for (var i = 0; i < arr.length; ++i) {
			var file = arr[i].path;
			if(util.isDir(file)){
				util.getAllFiles(file).then(function(files) {
					if(files.length == 0){
						return;
					}
					var _file = files[0];
					//解出目录名
					var dir = path.dirname(_file);
					var idx = dir.lastIndexOf('/');
					if(idx >= 0){
						dir = dir.substring(idx + 1);
					}else{
						dir = "";
					}
					files.forEach(function(_file) {
						self.tryAddSample(_file, dir);
					})
				});
			}else{
				this.tryAddSample(file);
			}

		}
		setTimeout(function(){
			ui.sync();
		}, 100);
	},

	tryAddSample: function(file, dir){
		var suffix = path.extname(file);
		if(suffix == '.wav' || suffix == '.mp3' || suffix == '.ogg'){
			this.addSample(file, dir);
		}
	},

	/**
	 * 有些地方引用的sample, 没有引用note, 加个桥接函数
	 * @param file
	 * @returns {*}
	 */
	getFilePath: function(file) {
		return note.getFilePath(file);
	},

	/**
	 * UI接口
	 */

	_getList: function () {
		return this.editInfo;
	},

	_setCurrent: function(name){
		this.current = name;
		event.trigger(event.events.grid.assign, {sample: name});
	}
};

module.exports = ret;
